#include "Argument.h"

class TypeClass : public ROSE_VisitorPattern {
    public:
        virtual void visit(SgTypeInt *) { printf("VISITING INT\n"); }
        virtual void visit(SgTypeChar *) { printf("VISITING CHAR\n"); }
        virtual void visit(SgPointerType *) { printf("VISITING PTR\n"); }
};

Argument::Argument() {
    child = NULL;
}

string Argument::typeStr() {
    return string("<error>");
}

int Argument::getOrder() {
    return 0;
}

IntArgument::IntArgument() : Argument() { }

string IntArgument::typeStr() {
    if(child == NULL) return string("int");
    return child->typeStr() + string("int");
}

int IntArgument::getOrder() {
    return 0;
}

PtrArgument::PtrArgument() : Argument() { }

string PtrArgument::typeStr() {
    if(child == NULL) return string("<ptr error>");
    return child->typeStr() + string("*");
}

int PtrArgument::getOrder() {
    return 1+child->getOrder();
}

CharArgument::CharArgument() : Argument() { }

string CharArgument::typeStr() {
    if(child == NULL) return string("char");
    return child->typeStr()+string("char");
}


int CharArgument::getOrder() {
    return 0;
}

string StructArgument::typeStr() {
    if(child == NULL) return name;
    return child->typeStr()+name;
}

int StructArgument::getOrder() {
    return 0;
}

Argument *translateArgsHelper(SgType *type) {
    SgTypeInt *intType = isSgTypeInt(type);
    SgPointerType *ptrType = isSgPointerType(type);
    SgTypeChar *charType = isSgTypeChar(type);
    SgClassType *classType = isSgClassType(type);

    if(intType != NULL) {
        return new IntArgument();
    } else if(ptrType != NULL) {
        return new PtrArgument();
    }else if(charType != NULL) {
        return new CharArgument();
    } else if(classType != NULL) {
        SgClassDeclaration *decl = (SgClassDeclaration *)(classType->get_declaration());
        return new StructArgument(decl->get_name());
    }
    return new Argument();
}

Argument *translateArgs(SgType *type) {

    if(type->containsInternalTypes()) {
        Rose_STL_Container<SgType *> internals = type->getInternalTypes();
        Argument *head = translateArgsHelper(type);
        Argument *curr = head;
        for(unsigned int i = 0; i < internals.size(); i++) {
            Argument *tmp = translateArgsHelper(internals[i]);
            curr->setChild(tmp);
            curr = tmp;
        }
        return head;
    }
    return translateArgsHelper(type);
}
